package org.caw.hbase.test.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Simple REST client for interaction with CAW web service
 * 
 * @author dino.keco
 * @version 0.1
 * @since 0.1
 */
@Ignore
public class CawRESTClient {

	private static final Logger LOGGER = LoggerFactory.getLogger(CawRESTClient.class);

	private String baseURL;

	private static final String APPLICATION_JSON = "application/json";
	private static final String UTF8 = "UTF-8";

	private static Map<String, CawRESTClient> INSTANCE = new HashMap<String, CawRESTClient>();

	public static enum Method {
		GET, POST, DELETE, PUT;
	}

	public static class CawClientResponse {
		private int status;
		private String body;
		private Map<String, String> header;

		public int getStatus() {
			return status;
		}

		public void setStatus(int status) {
			this.status = status;
		}

		public String getBody() {
			return body;
		}

		public void setBody(String body) {
			this.body = body;
		}

		public Map<String, String> getHeader() {
			return header;
		}

		public void setHeader(Map<String, String> header) {
			this.header = header;
		}
	}

	private CawRESTClient(String baseURL) {
		this.baseURL = baseURL;
	}

	public CawClientResponse executeMethod(String resource, Method m, String body, Map<String, String> header) {
		HttpClient client = new HttpClient();

		HttpMethod method = null;
		switch (m) {
		case DELETE:
			method = new DeleteMethod(baseURL + "/" + resource);
			break;
		case GET:
			method = new GetMethod(baseURL + "/" + resource);
			break;
		case POST:
			PostMethod postMethod = new PostMethod(baseURL + "/" + resource);
			if (body != null) {
				try {
					postMethod.setRequestEntity(new StringRequestEntity(body, APPLICATION_JSON, UTF8));
				} catch (UnsupportedEncodingException e) {
					LOGGER.error(e.getMessage(), e);
				}
			}
			method = postMethod;
			break;
		case PUT:
			PutMethod putMethod = new PutMethod(baseURL + "/" + resource);
			if (body != null) {
				try {
					putMethod.setRequestEntity(new StringRequestEntity(body, APPLICATION_JSON, UTF8));
				} catch (UnsupportedEncodingException e) {
					LOGGER.error(e.getMessage(), e);
				}
			}
			method = putMethod;
			break;
		}

		if (header != null) {
			for (Entry<String, String> entry : header.entrySet()) {
				method.addRequestHeader(entry.getKey(), entry.getValue());
			}
		}

		try {
			int status = client.executeMethod(method);
			CawClientResponse response = new CawClientResponse();
			response.setStatus(status);
			response.setBody(method.getResponseBodyAsString());
			Map<String, String> data = new HashMap<String, String>();
			for (Header h : method.getResponseHeaders()) {
				data.put(h.getName(), h.getValue());
			}
			response.setHeader(data);
			return response;
		} catch (HttpException e) {
			LOGGER.error(e.getMessage(), e);
		} catch (IOException e) {
			LOGGER.error(e.getMessage(), e);
		}
		return null;
	}

	public String getBaseURL() {
		return baseURL;
	}

	public void setBaseURL(String baseURL) {
		this.baseURL = baseURL;
	}

	public static CawRESTClient getInstance(String URL) {
		if (INSTANCE.get(URL) == null) {
			INSTANCE.put(URL, new CawRESTClient(URL));
		}
		return INSTANCE.get(URL);
	}
}
